1. /* sdfexpbs.cpp by K.Tsuru */
  2. // function ID = 3318 ver. 2.18
  3. // First version has been finished on 30 May 2003.
  4. // rewrite on 4 Aug 2016 since version 2.30
  5. /***************************************************
  6. It evaluates exp(x) using the binary splitting method.
  7. ****************************************************/
  8. #ifndef SN_H
  9. #include "sn.h"
  10. #endif
  11. //static const SDouble ONE(1.0);
  12. static const SLong S_BASE = Lpow10(4*DFIGURES); // consider efficiency of FFT mult.
  13. SDouble ExpBS(const SDouble& x) {
  14. // Check the sign of x.
  15. if( !x.Sign(3318) ) return ONE; // x = 0
  16. if( x.IsMLT(ONE) ) return (ONE + x); // |x| << 1.0, x*x = 0;
  17. SDouble X(x);
  18. bool posX = true;
  19. if(X.Sign() < 0) {
  20. posX = false; X.ChangeSign(3318);
  21. }
  22. // Here X > 0.
  23. ExpArgCheck(X, 3318); // over/underflow check ver 2.18
  24. SNBlock <SLFraction> slr;
  25. int k = SplitSDouble(X, slr, S_BASE); // very fast
  26. long ip = (long)slr(0).num.Low2();
  27. SDouble r = Expower(ip);
  28. SLong num, den, a, c;
  29. int i = 1;
  30. /***********************************************
  31. The first factor is evaluated by
  32. exp(num/den) = {exp(num/(den*divisor)}^divisor .
  33. ************************************************/
  34. static const int pow2 = 16;
  35. static const long divisor = 1L << pow2;
  36. num = slr(i).num; den = slr(i).den * divisor;
  37. i++;
  38. ExpBSR(num, den, a, c); // exp(num/den) = a/c (a rational number)
  39. SDouble f = SDouble(a)/SDouble(c); // = a/c
  40. f = Dpow(f, divisor);
  41. r *= f;
  42. /********************************************
  43. My note : Do not apply the fixed point mode,
  44. because summing up is not used,
  45. SDouble version is faster than SLong one.
  46. *********************************************/
  47. SDouble rA(ONE), rC(ONE);
  48. for( ; i < k; i++) {
  49. num = slr(i).num; den = slr(i).den;
  50. ExpBSR(num, den, a, c);
  51. rA *= SDouble(a); rC *= SDouble(c);
  52. }
  53. r *= rA;
  54. if(posX) { // r*(rA/rC)
  55. return r / rC;
  56. } else { // rC/(r*rA)
  57. return rC / r;
  58. }
  59. }

sdfexpbs.cpp : last modifiled at 2016/08/25 16:34:49(1,974 bytes)
created at 2017/10/07 10:22:50
The creation time of this html file is 2017/10/07 11:29:39 (Sat Oct 07 11:29:39 2017).